
package com.ttomato.game.framework.gl;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

import com.ttomato.game.framework.impl.GLGraphics;

public class Vertices {
    final GLGraphics mGlGraphics;
    final boolean mHasColor;
    final boolean mHasTexCoords;
    final int mVertexSize;
    final FloatBuffer mVertices;
    final ShortBuffer mIndices;

    public Vertices(GLGraphics glGraphics, int maxVertices, int maxIndices, boolean hasColor,
            boolean hasTexCoords) {
        mGlGraphics = glGraphics;
        mHasColor = hasColor;
        mHasTexCoords = hasTexCoords;
        mVertexSize = (2 + (mHasColor ? 4 : 0) + (mHasTexCoords ? 2 : 0)) * 4;

        ByteBuffer buffer = ByteBuffer.allocateDirect(maxVertices * mVertexSize);
        buffer.order(ByteOrder.nativeOrder());
        mVertices = buffer.asFloatBuffer();

        if (maxIndices > 0) {

            buffer = ByteBuffer.allocateDirect(maxIndices * Short.SIZE / 8);
            buffer.order(ByteOrder.nativeOrder());
            mIndices = buffer.asShortBuffer();
        } else {
            mIndices = null;
        }
    }

    public void setVertices(float[] vertices, int offset, int length) {
        mVertices.clear();
        mVertices.put(vertices, offset, length);
        mVertices.flip();
    }

    public void setIndices(short[] indices, int offset, int length) {
        mIndices.clear();
        mIndices.put(indices, offset, length);
        mIndices.flip();
    }

    public void bind() {
        GL10 gl = mGlGraphics.getGl();

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        mVertices.position(0);
        gl.glVertexPointer(2, GL10.GL_FLOAT, mVertexSize, mVertices);

        if (mHasColor) {
            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
            mVertices.position(2);
            gl.glColorPointer(4, GL10.GL_FLOAT, mVertexSize, mVertices);
        }

        if (mHasTexCoords) {
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
            mVertices.position(mHasColor ? 6 : 2);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, mVertexSize,
                    mVertices);
        }
    }

    public void unbind() {
        GL10 gl = mGlGraphics.getGl();

        if (mHasColor) {
            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        }

        if (mHasTexCoords) {
            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        }
    }

    public void draw(int primitiveType, int offset, int numVertices) {
        GL10 gl = mGlGraphics.getGl();

        if (null != mIndices) {
            mIndices.position(offset);
            gl.glDrawElements(primitiveType, numVertices, GL10.GL_UNSIGNED_SHORT,
                    mIndices);
        } else {
            gl.glDrawArrays(primitiveType, offset, numVertices);
        }
    }
}
